package com.smyh.protcol.device;

import com.smyh.UIM.device.DeviceUpdateFm;
import com.smyh.bean.DeviceMockInfo;
import com.smyh.bean.RFDeviceInfo;
import com.smyh.cache.DeviceMockInfoCache;
import com.smyh.cache.PreferenceCommon;
import com.smyh.cache.PreferenceSearcheParam;
import com.smyh.cache.UIM.MainCahce;
import com.smyh.cache.UIM.device.DeviceOptionFromCache;
import com.smyh.cache.UIM.device.DeviceUpdateFm_Cache;
import com.smyh.cache.UIM.host.HostUpdateFm_Cache;
import com.smyh.protcol.ProtcolStruts;
import com.smyh.util.AddCrc;
import com.smyh.util.HexStrUtil;

import org.apache.mina.core.buffer.IoBuffer;

public class CMDUtil {
	/**
	 * 查询外设参数
	 * 
	 * @return
	 */
	public static IoBuffer askOutParam(byte[] phAddrBytes, byte askSubset) {
		IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
		byte dataLength = 0x16;
		byte numP = 0x1;
		byte[] spaceBytes = { 0, 0, 0, 0 };
		byte[] searchParamBytes = getSearchParam();

		buffer.put(ProtcolStruts.START_SIGN).put(dataLength).put(ProtcolStruts.OUTER_ASK_CMD).put(numP).put(searchParamBytes)
				.put(phAddrBytes).put(askSubset).put(spaceBytes).flip();
		byte sumCrc = AddCrc.getCrc(buffer, 2, buffer.limit() - 1);

		IoBuffer sendBuffer = IoBuffer.allocate(0).setAutoExpand(true);
		/**
		 * 下发的数据需要加：FF
		 */
		sendBuffer.put((byte) 0xff).put(buffer).put(sumCrc).put(ProtcolStruts.END_SIGN).flip();

		return sendBuffer;
	}

	/**
	 * 
	 * @param phAddrBytes
	 *            -物理地址
	 * @param paramContent
	 *            -20个字节参数内容（第一个字节是标识）
	 * @return
	 */
	public static IoBuffer setOutParam(byte[] phAddrBytes, byte[] paramContent) {
		IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
		byte dataLength = 0x2f;
		byte numP = 0x1;
		byte[] spaceBytes5 = { 0, 0, 0, 0, 0 };
		byte[] searchParamBytes = getSearchParam();

		buffer.put(ProtcolStruts.START_SIGN).put(dataLength).put(ProtcolStruts.OUTER_PARAM_SET_CMD).put(numP).put(searchParamBytes)
				.put(phAddrBytes).put(spaceBytes5).put(paramContent).put(spaceBytes5).flip();
		byte sumCrc = AddCrc.getCrc(buffer, 2, buffer.limit() - 1);

		IoBuffer sendBuffer = IoBuffer.allocate(0).setAutoExpand(true);
		/**
		 * 下发的数据需要加：FF
		 */
		sendBuffer.put((byte) 0xff).put(buffer).put(sumCrc).put(ProtcolStruts.END_SIGN).flip();

		return sendBuffer;
	}

	/**
	 * 
	 * @return 返回读取指示器录波数据buffer
	 */
	public static IoBuffer readWaveData(byte type){
		IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
		byte[] dataHead = {(byte) 0xa4,(byte) 0xa8};
		byte dataLength = 0x7;
//		byte type = (byte) 0xdc;
		byte numP = 0;


		buffer.put(dataHead).put(dataLength).put(type).put(numP).flip();
		byte sumCrc = AddCrc.getCrc(buffer, 2, buffer.limit() - 1);

		IoBuffer sendBuffer = IoBuffer.allocate(0).setAutoExpand(true);
		/**
		 * 下发的数据需要加：FF
		 */
		sendBuffer.put(buffer).put(sumCrc).put(ProtcolStruts.END_SIGN).flip();

		return sendBuffer;
	}
	
	/**
	 * 参数中含有链路地址、次数、组号、相别
	 * @return 返回读取通讯主机的录波数据buffer
	 */
	public static IoBuffer readHostWaveData(byte type,byte counts,byte groupNum,byte phase){
		IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
		byte[] dataHead = {(byte) 0xa4,(byte) 0xa8};
		byte dataLength = 0xa;
//		byte type = (byte) 0xdc;
		byte numP = 0;


		buffer.put(dataHead).put(dataLength).put(type).put(numP)
			.put(counts).put(groupNum).put(phase).flip();
		byte sumCrc = AddCrc.getCrc(buffer, 2, buffer.limit() - 1);

		IoBuffer sendBuffer = IoBuffer.allocate(0).setAutoExpand(true);
		/**
		 * 下发的数据需要加：FF
		 */
		sendBuffer.put(buffer).put(sumCrc).put(ProtcolStruts.END_SIGN).flip();

		return sendBuffer;
	}
	/**
	 * 
	 * @return 返回读取录波数据buffer
	 */
	public static IoBuffer getUpdateForCMD(byte deviceIndex){
		IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
		byte[] dataHead = {(byte) 0xa4,(byte) 0xa8};
		byte dataLength = 0xc;
		//******************************
		//********************************
		byte type = (byte) 0xfc;

		byte[] dataAddr = {0,0,0,0,0};

		buffer.put(dataLength).put(type).put(deviceIndex)
			.put(dataAddr).flip();
		byte sumCrc = AddCrc.getCrc(buffer.duplicate());

		IoBuffer sendBuffer = IoBuffer.allocate(0).setAutoExpand(true);
		/**
		 * 
		 */
		sendBuffer.put(dataHead).put(buffer).put(sumCrc).put(ProtcolStruts.END_SIGN).flip();

		return sendBuffer;
	}
	
	
	/**
	 * 读取同步录波时间目录
	 * @return 返回读取同步时间录波目录数据buffer
	 */
	public static IoBuffer getCatalogForSync(){
		IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
		byte[] dataHead = {(byte) 0xa4,(byte) 0xa8};
		byte dataLength = 0x9;
		//******************************
		//********************************
		byte type = (byte) 0xe0;
		byte allFram = 1;
		byte[] contents = {1,0};

		buffer.put(dataLength).put(type).put(allFram)
			.put(contents).flip();
		byte sumCrc = AddCrc.getCrc(buffer.duplicate());

		IoBuffer sendBuffer = IoBuffer.allocate(0).setAutoExpand(true);
		/**
		 * 
		 */
		sendBuffer.put(dataHead).put(buffer).put(sumCrc).put(ProtcolStruts.END_SIGN).flip();

		return sendBuffer;
	}
	/**
	 * 读取故障录波时间目录
	 * @return 返回读取故障时间录波目录数据buffer
	 */
	public static IoBuffer getCatalogForFault(){
		IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
		byte[] dataHead = {(byte) 0xa4,(byte) 0xa8};
		byte dataLength = 0x9;
		//******************************
		//********************************
		byte type = (byte) 0xe1;
		byte allFram = 1;
		byte[] contents = {1,0};

		buffer.put(dataLength).put(type).put(allFram)
			.put(contents).flip();
		byte sumCrc = AddCrc.getCrc(buffer.duplicate());

		IoBuffer sendBuffer = IoBuffer.allocate(0).setAutoExpand(true);
		/**
		 * 
		 */
		sendBuffer.put(dataHead).put(buffer).put(sumCrc).put(ProtcolStruts.END_SIGN).flip();

		return sendBuffer;
	}
	
	/**
	 * 追加录波点位
	 * @param recordType 录波类型
	 * @param totalPack 总包数
	 * @param supaddByte 表示包号（1表示需要重发，同步录波第一个字节一直为0）
	 * @return
	 */
	public static IoBuffer superaddRecordPoint(byte recordType,byte totalPack,byte[] supaddByte){
		
		IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
		byte[] dataHead = {(byte) 0xa4,(byte) 0xa8};
		byte dataLength = (byte) (supaddByte.length + 7);
		buffer.put(dataLength).put(recordType).put(totalPack).put(supaddByte).flip();
		byte sumCrc = AddCrc.getCrc(buffer.duplicate());

		IoBuffer sendBuffer = IoBuffer.allocate(0).setAutoExpand(true);
		sendBuffer.put(dataHead).put(buffer).put(sumCrc).put(ProtcolStruts.END_SIGN).flip();
		return sendBuffer;
		
		
	}
	/**
	 * 遥控指令：根据子指令来获取指令
	 *
	 * @param phAddrBytes
	 * @param subType
	 *            :1-指示器报一次短路、2-指示器报一次接地、3-指示器复归 4-备用、5-启动指示器标定、6-召唤指示器数据（遥信、遥测）
	 * @return
	 */
	public static IoBuffer controlByType(byte[] phAddrBytes, byte subType,byte subType2) {
		IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
		byte dataLength = 0x25;
		byte numP = 0x1;
		// 18字节空白(byte & 0xf0);
		byte[] spaceBytes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
		// 19字节空白(byte & 0xf0);
		byte[] searchParamBytes = getSearchParam();

		IoBuffer bufT = IoBuffer.allocate(0).setAutoExpand(true);
		bufT.put(phAddrBytes).flip();
		String physicAddr = bufT.getHexDump();
		RFDeviceInfo obj = MainCahce.deviceInfos.get(physicAddr);
		if(obj==null){
//			UIElement.showMessageDialog("没有选中设备");
			obj = new RFDeviceInfo();
			byte[] groupAddr = {0,0,0};
			obj.setGroupAddr(groupAddr);
			obj.setLinePhaseOff((byte) 0);
		}
		buffer.put(ProtcolStruts.START_SIGN).put(dataLength).put(ProtcolStruts.OUTER_CONTROL_CMD).put(numP).put(searchParamBytes)
				.put(obj.getGroupAddr()).put(obj.getLinePhaseOff()).put(subType).put(subType2).put(spaceBytes)
				.flip();
		byte sumCrc = AddCrc.getCrc(buffer, 2, buffer.limit() - 1);

		IoBuffer sendBuffer = IoBuffer.allocate(0).setAutoExpand(true);
		/**
		 * 下发的数据需要加：FF
		 */
		sendBuffer.put((byte) 0xff).put(buffer).put(sumCrc).put(ProtcolStruts.END_SIGN).flip();

		return sendBuffer;
	}

	/**
	 * 遥控指令：根据子指令来获取指令
	 *
	 * @param phAddrBytes
	 * @param subType
	 *            :1-指示器报一次短路、2-指示器报一次接地、3-指示器复归 4-备用、5-启动指示器标定、6-召唤指示器数据（遥信、遥测）
	 * @return
	 */
	public static IoBuffer controlByTypeSelfCmd(byte[] phAddrBytes, byte subType,byte subType2) {
		IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
		byte dataLength = 0x25;
		byte numP = 0x1;
		// 18字节空白(byte & 0xf0);
		byte[] spaceBytes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
		// 19字节空白(byte & 0xf0);
		byte[] searchParamBytes = getSearchParam();

		buffer.put(ProtcolStruts.START_SIGN).put(dataLength).put(ProtcolStruts.OUTER_CONTROL_CMD).put(numP).put(searchParamBytes)
				.put(phAddrBytes).put(subType).put(subType2).put(spaceBytes)
				.flip();
		byte sumCrc = AddCrc.getCrc(buffer, 2, buffer.limit() - 1);

		IoBuffer sendBuffer = IoBuffer.allocate(0).setAutoExpand(true);
		/**
		 * 下发的数据需要加：FF
		 */
		sendBuffer.put((byte) 0xff).put(buffer).put(sumCrc).put(ProtcolStruts.END_SIGN).flip();

		return sendBuffer;
	}

	/**
	 * 获取搜索条件字节数组方法：
	 * @return
	 */
	private static byte[] getSearchParam(){
		byte callTimes = (byte) PreferenceCommon.sPreferences.getInt(PreferenceSearcheParam.RF_CALL_TIME,5);
		byte waitTimes = (byte) PreferenceCommon.sPreferences.getInt(PreferenceSearcheParam.RF_WAIT_TIME,30);
		byte callDistance = (byte) PreferenceCommon.sPreferences.getInt(PreferenceSearcheParam.RF_CALL_DISTANCE,12);
		byte freqChanel = (byte) PreferenceCommon.sPreferences.getInt(PreferenceSearcheParam.RF_COMM_FREQ,16);
		byte commFreqChanel = (byte) PreferenceCommon.sPreferences.getInt(PreferenceSearcheParam.RF_CALL_CHANEL,28);

		byte[] searchParamBytes = new byte[5];
		searchParamBytes[0] = callTimes;
		searchParamBytes[1] = waitTimes;
		searchParamBytes[2] = callDistance;
		searchParamBytes[3] = freqChanel;
		searchParamBytes[4] = commFreqChanel;

		return searchParamBytes;
	}

	/** @return 升级报文方法：指示器 */
	public static IoBuffer getUpdatePack(byte[] sendBytes, int dataAddr) {
		IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
		byte[] dataHead = { (byte) 0xa4, (byte) 0xa8 };
		byte dataLength = (byte) (sendBytes.length + 11);
		byte type = (byte) 0xcc;
		byte phaseByte = -1;
		if (DeviceUpdateFm_Cache.updateType == 1) {
			phaseByte = DeviceUpdateFm_Cache.phaseNum;
		} else if (DeviceUpdateFm_Cache.updateType == 0) {
			phaseByte = DeviceUpdateFm_Cache.selectedHostDeviceIndex;
		}
		buffer.put(dataLength).put(type).put(phaseByte).putInt(dataAddr).put(sendBytes).flip();
		byte sumCrc = AddCrc.getCrc(buffer.duplicate());
		IoBuffer sendBuffer = IoBuffer.allocate(0).setAutoExpand(true);
		sendBuffer.put(dataHead).put(buffer).put(sumCrc).put(ProtcolStruts.END_SIGN).flip();
		return sendBuffer;
	}
	public static IoBuffer getUpdatePackSuccForHost() {
		IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
		byte[] dataHead = { (byte) 0xa4, (byte) 0xa8 };
		byte dataLength = (byte) 0x09;
		//
		byte phaseByte = HostUpdateFm_Cache.selectedHostDeviceIndex;
		byte type = (byte) 0xcc;
		buffer.put(dataLength).put(type).put(phaseByte).put((byte) 0x0A).put((byte) 1).flip();
		byte sumCrc = AddCrc.getCrc(buffer);
		IoBuffer sendBuffer = IoBuffer.allocate(0).setAutoExpand(true);
		/**
		 *
		 */
		sendBuffer.put(dataHead).put(buffer).put(sumCrc).put(ProtcolStruts.END_SIGN).flip();
		return sendBuffer;
	}


}
